package org.chnxi.study.concurrent.abc.demo;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;

/**
 * 使用synchronized实现
 */
public class Demo3 implements Serializable {

    public static class SyncABC{

        // 0 -> run printA
        // 1 -> run printB
        // 2 -> run printC
        int flag = 0;

        public synchronized void printA() {
            System.out.println(Thread.currentThread().getName()+":获取锁[A]");
            try{
                while (true){
                    if(flag == 0){
                        System.out.println("A");
                        flag = 1;
                        notifyAll();
                        break;
                    }
                    wait();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        public synchronized void printB() {
            System.out.println(Thread.currentThread().getName()+":获取锁[B]");
            try{
                while (true){
                    if(flag == 1){
                        System.out.println("B");
                        flag = 2;
                        notifyAll();
                        break;
                    }
                    wait();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        public synchronized void printC() {
            System.out.println(Thread.currentThread().getName()+":获取锁[C]");
            try{
                while (true){
                    if(flag == 2){
                        System.out.println("C");
                        flag = 0;
                        notifyAll();
                        break;
                    }
                    wait();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) {
        SyncABC abc = new SyncABC();
        Thread ta = new Thread(()->{
            try {
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            abc.printA();
        });

        Thread tb = new Thread(()->{
            abc.printB();
        });

        Thread tc = new Thread(()->{
            abc.printC();
        });

        ta.start();
        tb.start();
        tc.start();
    }

}
